Skip to content

feat: unreliable datagram support (QUIC + libp2p-datagram)#6489

Open
royzah wants to merge 8 commits into
libp2p:masterfrom
royzah:feat/quic-datagrams
Open

feat: unreliable datagram support (QUIC + libp2p-datagram)#6489
royzah wants to merge 8 commits into
libp2p:masterfrom
royzah:feat/quic-datagrams

Conversation

@royzah

@royzah royzah commented Jun 17, 2026

Copy link
Copy Markdown

Description

Adds unreliable datagram support to libp2p, end to end:

  • core: StreamMuxer::send_datagram / max_datagram_size and StreamMuxerEvent::Datagram (default: unsupported).
  • quic: implements them over quinn datagrams, enabled by default and configurable.
  • swarm: ConnectionEvent::Datagram (inbound) and ConnectionHandlerEvent::SendDatagram (outbound).
  • New libp2p-datagram crate: a Behaviour + Control with send_datagram(peer, ...) and an IncomingDatagrams stream.

Motivation and prior art: libp2p/specs#626 (IP over libp2p), #225, and the MTU edge in #4647. Tunnelling IP over reliable, ordered streams is 2-10x slower (HOL blocking; TCP-over-TCP meltdown); a datagram carrier fixes it.

Notes

  • Muxer trait methods default to unsupported, so other muxers are unaffected.
  • quic::poll now surfaces connection close via the datagram future (was always Pending).
  • Tests: quic datagram roundtrip, datagram-crate e2e over QUIC, swarm unit tests.

Open questions

  • Datagrams default to on in quic::Config; happy to make it opt-in.
  • Should the new enum variants be #[non_exhaustive]?

royzah added 5 commits June 17, 2026 12:57
Signed-off-by: Royyan Zahir <muhammad.royyan@tii.ae>
Signed-off-by: Royyan Zahir <muhammad.royyan@tii.ae>
…hangelog

Signed-off-by: Royyan Zahir <muhammad.royyan@tii.ae>
Signed-off-by: Royyan Zahir <muhammad.royyan@tii.ae>

@jxs jxs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, and thanks for starting this!
as commented on your specs post, wdyt of implementing libp2p/specs#680 and go from there? You're in need for this in production right? That would be a nice testbed for the spec

@royzah

royzah commented Jun 17, 2026

Copy link
Copy Markdown
Author

Nice, that's the direction we were hoping for. The quic/core/swarm bits here are the datagram primitive #680 needs anyway, so I'll keep those and rework the libp2p-datagram crate to match #680: /dg/1 control stream, app-proto-id prefix, Control StreamID varint per datagram. One extra bit I'll need is exposing the control stream's QUIC stream id through the muxer, since #680 keys on it. We'll run it on our radio mesh and report back.

@royzah

royzah commented Jun 18, 2026

Copy link
Copy Markdown
Author

Hey @jxs, while you're here, mind also casting an eye over #6487 (Control::open_stream_on_connection)? It's a small one and we need it in production too, alongside the datagram work.
WDYT ?

@royzah

royzah commented Jun 18, 2026

Copy link
Copy Markdown
Author

specs#680 is implemented here: /dg/1 control stream + app proto id, datagrams keyed by the control stream's QUIC id (via a new StreamMuxer::substream_id), inbound filtered by it. Tests green over QUIC. Radio-mesh bench next, will report numbers.

Two spec notes: one app-protocol per behaviour for now, and we drop on a bad/unknown stream id rather than raising PROTOCOL_VIOLATION (not reachable from this layer).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants